package com.conversationboard.model.sockpuppets;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.conversationboard.database.Database;
import com.conversationboard.database.Queries;

public class Sockpuppets {

	public static List<List<Sockpuppet>> getSockpuppets(SockpuppetSearchType type) throws SQLException {

		String query = Queries.MORE_THAN_ONE_PASSWORD;
		String keyField = "password";
		List<String> valuesToIgnore = new ArrayList<String>();

		if (type == SockpuppetSearchType.IPADDRESS) {
			query = Queries.MORE_THAN_ONE_IPADDRESS;
			keyField = "ipaddress";
			valuesToIgnore.add("0.0.0.0");
			valuesToIgnore.add("0:0:0:0:0:0:0:1%0");
		}

		Connection connection = null;

		Map<String, String> keys = new HashMap<String, String>();
		Map<String, List<Sockpuppet>> sockpuppets = new HashMap<String, List<Sockpuppet>>();

		try {

			/* Get all the instances of passwords that there are more than one of */

			connection = Database.getConnection();

			PreparedStatement statement = connection.prepareStatement(query);
			statement.execute();

			ResultSet resultSet = statement.getResultSet();

			while (resultSet.next()) {
				String key = resultSet.getString(keyField);
				keys.put(key, key);
			}

			statement.close();

			/* Now iterate through all users that have one of these passwords. */

			statement = connection.prepareStatement(Queries.GET_ALL_USERS);
			statement.execute();

			resultSet = statement.getResultSet();

			while (resultSet.next()) {

				String key = resultSet.getString(keyField);

				if (valuesToIgnore.contains(key)) {
					continue;
				}

				if (keys.containsKey(key)) {
					if (sockpuppets.containsKey(key)) {

						List<Sockpuppet> list = sockpuppets.get(key);

						Sockpuppet sockpuppet = new Sockpuppet();
						sockpuppet.setLoginId(resultSet.getString("loginid"));

						String originalDisplayName = resultSet.getString("originaldisplayname");

						if (originalDisplayName != null) {
							sockpuppet.setDisplayName(resultSet.getString("displayname") + " (" + resultSet.getString("originaldisplayname") + ")");
						} else {
							sockpuppet.setDisplayName(resultSet.getString("displayname"));
						}

						sockpuppet.setLastLoggedIn(resultSet.getTimestamp("lastloggedin"));
						sockpuppet.setCreationDate(resultSet.getTimestamp("creationdate"));
						sockpuppet.setPermanent(resultSet.getBoolean("permanent"));

						list.add(sockpuppet);

					} else {

						Sockpuppet sockpuppet = new Sockpuppet();
						sockpuppet.setLoginId(resultSet.getString("loginid"));

						String originalDisplayName = resultSet.getString("originaldisplayname");

						if (originalDisplayName != null) {
							sockpuppet.setDisplayName(resultSet.getString("displayname") + " (" + resultSet.getString("originaldisplayname") + ")");
						} else {
							sockpuppet.setDisplayName(resultSet.getString("displayname"));
						}

						sockpuppet.setLastLoggedIn(resultSet.getTimestamp("lastloggedin"));
						sockpuppet.setCreationDate(resultSet.getTimestamp("creationdate"));
						sockpuppet.setPermanent(resultSet.getBoolean("permanent"));

						List<Sockpuppet> list = new LinkedList<Sockpuppet>();
						list.add(sockpuppet);

						sockpuppets.put(key, list);
					}
				}
			}

			List<List<Sockpuppet>> listOfSockpuppets = new LinkedList<List<Sockpuppet>>();

			for (Map.Entry<String, List<Sockpuppet>> entry : sockpuppets.entrySet()) {
				List<Sockpuppet> list = entry.getValue();
				listOfSockpuppets.add(list);
			}

			return listOfSockpuppets;

		} finally {
			Database.close(connection);
		}

	}

}
